using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using eyeArchive.Sql;

namespace eyeArchive.Core
{
	public class Column
	{
		#region "Members"
		private Table parent;
		private string name;
		private string type;
		private int length;
		private int precision;
		private int scale;
		private bool isKey;
		private Statuses status;
		private Actions action;
		private bool isNullable;
		private bool isId;
		#endregion

		#region "Constructors"
		internal Column(Table parent, SqlDataReader row)
		{
			// =====================================================================
			// === Pre-Process                                                   ===
			// =====================================================================
			// === Intialize variables =============================================
			status = Statuses.NotInstalled;
			action = Actions.None;

			// === Save the parameters =============================================
			if (parent != null)
				this.parent = parent;
			else
				throw new ArgumentNullException("The parent object cannot be null");

			name = row["colName"].ToString();
			type = row["colType"].ToString();
			length = int.Parse(row["colLength"].ToString());
			precision = int.Parse(row["colPrecision"].ToString());
			scale = int.Parse(row["colScale"].ToString());
			isNullable = (row["isNullable"].ToString() == "0" ? false : true);
			isId = (bool)row["isId"];
			if (isId)
				parent.NeedsIdentity_Insert = true;
		}
		#endregion

		#region "Properties"
		internal Table Parent
		{
			get { return parent; }
		}

		public string Name
		{
			get { return name; }
		}

		internal string Type
		{
			get { return type; }
		}

		internal int Length
		{
			get { return length; }
		}

		internal int Scale
		{
			get { return scale; }
		}

		internal int Precision
		{
			get { return precision; }
		}

		internal bool IsNullable
		{
			get { return isNullable; }
		}

		internal Statuses Status
		{
			get { return status; }
			set
			{
				if (status != value)
				{
					status = value;
					SetAction(action);
				}
			}
		}

		internal Actions Action
		{
			get { return action; }
		}

		internal bool IsKey
		{
			get { return isKey; }
			set { isKey = value; }
		}

		internal bool IsID
		{
			get { return isId; }
		}
		#endregion


		internal bool IsTypeStrict()
		{
			return (SqlConvert.GetTypeMask(type, false, true) == null ? false : true);
			return true;// (SqlConvert.GetTypeMask(type, false) == null ? false : true);
		}

		#region "Methods"
		internal void SetAction(Actions value)
		{
			if (action != value)
			{
				switch (value)
				{
					case Actions.None:
						action = value;
						break;
					case Actions.Install:
						if (status == Statuses.NotInstalled)
							//if (SqlConvert.GetTypeMask(type) != null)
							action = value;
						/*else
						{
							action = Actions.None;
							System.Windows.Forms.MessageBox.Show(String.Format("The column [{0}].[{1}].[{2}] has been skipped due to the following error:\n- This data type does not support logging", parent.PrimarySchema, parent.PrimaryTable, name));
						}*/
						else
							throw new InvalidOperationException(string.Format("Cannot apply the action [{0}] on the column [{1}]: it already has the status [{2}]", value, name, status));
						break;
					case Actions.Uninstall:
						if (status == Statuses.Installed)
							action = value;
						else
							throw new InvalidOperationException(string.Format("Cannot apply the action [{0}] on the column [{1}]: it already has the status [{2}]", value, name, status));
						break;
					default:
						throw new InvalidOperationException(string.Format("Unmanaged action [{0}]", value));
				}
			}
		}

		public override string ToString()
		{
			return string.Format("[{0}] {1} {2}",
				name,
				string.Format(SqlConvert.GetTypeMask(type), type, length, (length == -1 ? "MAX" : Precision.ToString()), precision, scale),
				(isNullable ? "NULL" : "NOT NULL"));
		}

		// Used to create a parameter in stored procedure.
		// Return FieldName AS FieldType
		internal string ToString2()
		{
			return string.Format("{0} AS {1}",
	name,
					string.Format(SqlConvert.GetTypeMask(type), type, length, (length == -1 ? "MAX" : Precision.ToString()), precision, scale));
		}
		#endregion
	}
}
